TOOL.Category		= "Construction" 
TOOL.Name		= "#Bridge Tool" 
TOOL.Command		= nil 
TOOL.ConfigName		= ""

cleanup.Register( "bridge" ) 
CreateConVar( "sbox_maxbridge", 30, FCVAR_NOTIFY )
CreateConVar( "sbox_maxbridgelength", 15, FCVAR_NOTIFY )

if CLIENT then 

	language.Add( "Tool_bridgetool_name", "Bridge Tool" ) 
	language.Add( "Tool_bridgetool_desc", "Spawns a Bridge" ) 
	language.Add( "Tool_bridgetool_0", "Left click to set start point" )
	language.Add( "Tool_bridgetool_1", "Left click to set end point and spawn" )
	language.Add( "Undone_bridge", "Undone Bridge" )
	language.Add( "Cleanup_bridge", "Bridges" )
	language.Add( "Cleaned_bridge", "Cleaned Up Bridges" )
	language.Add( "SBoxLimit_bridge", "You've hit the Bridge limit!" )

end 

TOOL.ClientConVar[ "key" ] = "-1"
TOOL.ClientConVar[ "ladder" ] = "0"

local model = "models/props_building_details/Storefront_Template001a_Bars.mdl"
util.PrecacheModel( model )

local origin = Vector( 0, 0, 0 )
local Point1 = origin
local Point2 = origin

function TOOL:GoBridge()

	local pl = self:GetOwner() 
	
	local key = self:GetClientNumber( "key" )
	local ladder = self:GetClientNumber( "ladder" ) == 1
	
	
	-- Returns a table.
	local bridges, ladderents = MakeBridges( pl, Point1, Point2, ladder )

	-- Use the first piece as the controller
	numpad.OnDown( pl, key, "Bridge_Toggle", bridges[ 1 ] )
	bridges[ 1 ].BridgeController = true
	bridges[ 1 ].BridgeEnts = bridges
	bridges[ 1 ].LadderEnts = ladderents
	
	undo.Create( "bridge" )
	
	for k, bridge in pairs( bridges ) do 
	
		undo.AddEntity( bridge )
		pl:AddCleanup( "bridge", bridge )
		bridge.IsLadder = ladder
		
	end
	for k, ent in pairs( ladderents ) do

		undo.AddEntity( v )
		pl:AddCleanup( "bridge", v )
	
	end
	
	undo.SetPlayer( pl )
	undo.Finish()

end

function TOOL:LeftClick( trace ) 
   
	if trace.Entity && trace.Entity:IsPlayer() then return false end 
	if CLIENT then return true end 
	 
	-- If there's no physics object then we can't constraint it! 
	if SERVER && attach && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) then return false end 
	 
	if Point1 == origin then 
	
		self:SetStage(1)
		Point1 = trace.HitPos
		
	elseif Point2 == origin then
	
		self:SetStage(0)
		Point2 = trace.HitPos
		
		self:GoBridge()
		
		Point1 = origin
		Point2 = origin
		
	end
	
	return true
  
end 
  
function TOOL:RightClick( trace ) 
  
	if trace.Entity && trace.Entity:IsPlayer() then return false end 
	if CLIENT then return true end 
	 
	-- If there's no physics object then we can't constraint it! 
	if SERVER && attach && !util.IsValidPhysicsObject( trace.Entity, trace.PhysicsBone ) then return false end 
	
	Point1 = trace.HitPos
	local trace2 = util.QuickTrace( Point1, trace.HitNormal*2048, self.Owner )
	Point2 = trace2.HitPos
	
	self:GoBridge()
	
	Point1 = origin
	Point2 = origin
  
end 
  
function TOOL.BuildCPanel( CPanel ) 
  
	CPanel:AddControl( "Header", { Text = "#Tool_bridgetool_name", Description	= "#Tool_bridgetool_desc" }  ) 
	CPanel:AddControl( "Numpad", { Label = "Key", ButtonSize = "22", Command = "bridgetool_key" } )
	CPanel:AddControl( "Checkbox", { Label = "Create Ladder", Command = "bridgetool_ladder" } )
									 
end 

if SERVER then
	local function MakeLadder( Point1, Point2 )
		-- Thanks high. http://forums.facepunchstudios.com/showthread.php?t=264489
		local start = ents.Create( "func_useableladder" )
		local endpoint1 = ents.Create( "info_ladder_dismount" )
		local endpoint2 = ents.Create( "info_ladder_dismount" )
		local origin = (Point2 - Point1)
		
		--start:SetKeyValue( "targetname", "ladder_" .. math.Ran( 0, 1000 ) )
		start:SetKeyValue( "origin", tostring( Point1 ) )
		start:SetKeyValue( "point0", tostring( Point1 ) )
		start:SetKeyValue( "point1", tostring( Point2 ) )
		
		start:SetPos( Point1 )
		endpoint1:SetPos( Point1 )
		endpoint2:SetPos( Point2 )
		
		endpoint1:SetParent( start )
		endpoint2:SetParent( start )
		
		start:Spawn()
		endpoint1:Spawn()
		endpoint2:Spawn()
		
		start:Activate()
		endpoint1:Activate()
		endpoint2:Activate()
		return start, endpoint1, endpoint2
	end
	function MakeBridges( pl, Point1, Point2, ladder )
	
		local BridgeEnts = {}
		local LadderEnts = {}
		
		-- This is used to calculate the positions of each entity.
		local BridgeLength = 104.5
		
		-- Angle between first and second point.
		local ang = (Point1 - Point2):Angle()
		
		local lastent
		
		-- Loop through to max bridge pieces. It will stop early if we run out of space
		local maxlength = server_settings.Int( "sbox_maxbridgelength" )
		
		for i=1, maxlength do
		
			-- This counts each bridge piece
			if ( !pl:CheckLimit( "bridge" ) ) then break end
			
			local pos
			
			-- First piece can go through objects.
			if !lastent then 
			
				-- First point plus half a bridgepiece length. This is to align
				-- it nicely.
				pos = Point1 - ang:Forward() * BridgeLength/2
				
			else
			
				-- The position of the next bridge piece.
				pos = lastent:GetPos() - lastent:GetUp() * BridgeLength
				--pos = lastent:LocalToWorld( Vector( 0,0,-104.5 ) )
				
				-- I don't remember why I added this line but there must have been a reason.
				if( (pos - Point1):Length() > (Point2 - Point1):Length() ) then break end
				
				-- Second piece can go through objects.
				if i > 2 then
					
					local trace = {}
					
					trace.start = lastent:GetPos()
					trace.endpos = pos
					trace.filter = lastent
					
					local traceR = util.TraceLine( trace )
					
					-- Something is in the way and the trace didn't complete at least half way
					if( traceR.Fraction < 0.5 ) then break end
					
				end
				
			end
			
			
			local e = ents.Create( "bridgepiece" )
			
			e:SetPos( pos )
			e:SetAngles( ang + Angle( 90,0,0 ) )
			e:SetModel( model )
			
			e:Spawn()
			
			pl:AddCount( "bridge", e )
			
			if( e:GetPhysicsObject():IsValid() ) then
				e:GetPhysicsObject():EnableMotion( false )
			end
			
			-- Record this as the last entity we've made
			lastent = e
			
			-- Add this to the list
			BridgeEnts[ #BridgeEnts+1 ] = e
			
		end
		
		if ladder then
		
			local offset = 30
			local start1, end11, end12 = MakeLadder( Point1 + lastent:GetForward()*offset, Point2 + lastent:GetForward()*offset )
			
			local start2, end21, end22 = MakeLadder( Point1 - lastent:GetForward()*offset, Point2 - lastent:GetForward()*offset )
			
			LadderEnts = { start1, end11, end12, start2, end21, end22 }
		
		end
		
		return BridgeEnts, LadderEnts
	end
	
	-- No duplicator support yet
	
end